<?php

use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;

/**
 * 随机概率数组
 * @param array $ps array('a'=>0.5,'b'=>0.2,'c'=>0.4)
 * @return mixed
 */
function randomArray($ps){
    static $arr = array();
    $key = md5(serialize($ps));

    if (!isset($arr[$key])) {
        $max = array_sum($ps);
        foreach ($ps as $k=>$v) {
            $v = $v / $max * 10000;
            for ($i=0; $i<$v; $i++) $arr[$key][] = $k;
        }
    }
    return $arr[$key][mt_rand(0,count($arr[$key])-1)];
}

/**
 * 根据多个参数进行切割
 * @param array $exploderData
 * @param string $string
 * @param array $data
 * @return mixed|null
 */
function exploders($exploderData = [],&$string = '',$data = [])
{
    foreach ($exploderData as $v) {
        if(is_string($string)) {
            $string = explode($v,$string);
        }elseif (is_array($string)) {
            foreach ($string as $vs) $data[] = explode($v,$vs);
        }
    }
    return array_reduce($data,'array_merge',[]);
}

/**
 * 根据单个字母获取庄闲的中文值
 * @param string $letter
 * @return string
 */
function getChineseBySingleLetter($letter = '')
{
    switch (strtolower($letter)) {
        case 'z':
            $value = '庄';
            break;
        case 'x':
            $value = '闲';
            break;
        case 'h':
            $value = '和';
            break;
        case 'j':
            $value = '庄对';
            break;
        case 'k':
            $value = '闲对';
            break;
        default:
            $value = $letter;//无法识别返回回去
    }
    return $value;
}

/**
 * 根据一个或者一组字符返回相应的数组
 * @param array|string $fields
 * @param array $array
 * @return array
 */
function getNewArrayByFields($fields = [],$array = [])
{
    $new_array = [];
    if (is_string($fields)) $fields = [$fields];
    foreach ($array as $k=>$v) {//一组
        foreach ($v as $ks=>$vs) {
            if(in_array($ks,$fields)) $new_array[$k][$ks] = $vs;
        }
    }
    return $new_array;
}

/**
 * 根据投注信息获取到投注金额和投注内容
 * @param string $content
 * @return array
 */
function matchFocusContent($content = '')
{
    preg_match("/[0-9]+/u",$content,$num);
    preg_match("/[a-z]/u",$content,$message);
    return ['money'=>reset($num),'message'=>reset($message)];
}

/**
 * 根据指定字段获取相匹配的数组(根据二维数组)
 * @param array $data
 * @param array $fields example ['field'=>'value','field1'=>'value1']
 * @param array $newData
 * @return array
 */
function getValuesByField($data = [],$fields = [],$newData = [])
{
    foreach ($data as $k=>$v) {
        $init = 0;
        foreach ($fields as $field=>$value) {
            if($v[$field] == $value) $init++;
        }
        if(count($fields)==$init) $newData[$k] = $v;
    }
    return $newData;
}

/**
 * 根据单个或者多个键获取指定值并返回数组(根据二维数组)
 * @param array $data
 * @param string|array $key
 * @param array $Values
 * @return array
 */
function getValuesByKeys($data = [],$key = '',&$Values = []) {
    if(is_string($key)){
        return $data[$key];
    }elseif (is_array($key)){
        foreach ($key as $v) {
            $Values[$v] = getValuesByKeys($data,strval($v),$Values);
        }
        return $Values;
    }
}

/**
 * Byte转换为其他(kb,mb,gb,tb)
 * @param $num
 * @return string
 */
function getFileSize($num){
    $p = 0;
    $format='bytes';
    if($num>0 && $num<1024){
        $p = 0;
        return number_format($num).' '.$format;
    }
    if($num>=1024 && $num<pow(1024, 2)){
        $p = 1;
        $format = 'KB';
    }
    if ($num>=pow(1024, 2) && $num<pow(1024, 3)) {
        $p = 2;
        $format = 'MB';
    }
    if ($num>=pow(1024, 3) && $num<pow(1024, 4)) {
        $p = 3;
        $format = 'GB';
    }
    if ($num>=pow(1024, 4) && $num<pow(1024, 5)) {
        $p = 3;
        $format = 'TB';
    }
        $num /= pow(1024, $p);
    return number_format($num, 3).' '.$format;
}

/**
 * 验证二维数组的长度是否一致
 * @param array $data
 * @return bool
 */
function matchLengthByTwoArray($data = [])
{
    $initData = [];
    foreach ($data as $k=>$v) $initData[] = count($v);
    return count(array_unique($initData))==1?boolval(1):false;
}

/**
 * 返回被整除的整型
 * @param int $beNum
 * @param int $num
 * @return int
 */
function returnBeDivInt($beNum = 0,$num = 0)
{
    if($beNum>$num) return returnBeDivInt($beNum-$num,$num);
    return $beNum;
}

/**
 * 往定义的二维数组追加值 (todo 与twoArrayCreate相称)
 * @param array $array (旧数据)
 * @param string $value (填入值)
 * @param int $begin (开始位置)从零开始11即是12
 * @param string $pattern (模式 cols(列)|rows(行))
 * @param int $init (初始化)
 * @return array
 */
function setTwoArrayValue($array = [], $value = '', $begin = 0, $pattern = 'cols',$init = 0)
{
    $rows_length = count($array);//行长度
    for ($i = 0; $i < $rows_length; $i++) {//遍历行数据
        $cols_length = count($array[$i]);//列长度
        for ($j = 0; $j < $cols_length; $j++) {//遍历列数据
            if ($init == $begin) {
                if ($pattern == 'cols') $array[$i][$j] = $value;//列
            }
            $init++;
        }
    }
    if ($pattern == 'rows') {
        $array[returnBeDivInt(($begin + 1), $rows_length)][floor(($begin + 1) / $rows_length)] = $value;
    }
    return $array;
}

/**
 * 创建二维数组(值为空) (todo 与setTwoArrayValue相称)
 * @param int $rows (行)
 * @param int $cols (列)
 * @param string $default
 * @return array
 */
function twoArrayCreate($rows = 0, $cols = 0 , $default = '')
{
    $data = [];
    for ($j = 0; $j < $cols; $j++) {
        for ($i = 0; $i < $rows; $i++) {
            $data[$i][$j] = $default;
        }
    }
    return $data;
}

/**
 * 二维数组中通过某个字段值重新创建新的二维数组
 * @param array $old_array
 * @param string $column
 * @return array
 */
function createArrayByColumn($old_array = [], $column = '')
{
    $new_array = [];
    foreach ($old_array as $array) $new_array[$array[$column]][] = $array;
    return $new_array;
}

/**
 * 获取目录下所有文件信息
 * @param string $file_path
 * @param array $files
 * @param array $getFiles
 * @return array
 */
function getDirectoryToArray($file_path = '', $files = [], $getFiles = [])
{
    $files = [];
    $handler = opendir($file_path);
    while (($filename = readdir($handler)) !== false) {
        // 务必使用!==，防止目录下出现类似文件名“0”等情况
        if ($filename !== "." && $filename !== "..") $files[] = $filename;
    }
    closedir($handler);
    // 打印所有文件名
    foreach ($files as $value) $getFiles[] = $file_path . '/' . $value;
    return $getFiles;
}

/**
 * 递归创建目录
 * @param $dir
 * @return bool
 */
function createDirectory($dir)
{
    return is_dir($dir) or createDirectory(dirname($dir)) and mkdir($dir, 0777);
}

/**
 * 生成查询语句(TODO 暂未完善)
 * @param $table
 * @param string $field
 * @param array $where
 * @param string $type
 * @return string
 */
function createSelectSql($table, $field = '*', $where = [], $type = 'select')
{
    $whereStr = '';
    if ($where) if (is_array($where)) {
        foreach ($where as $k => $v) $whereStr .= $k ? "`{$k}` = '{$v}'" : "and `{$k}` = '{$v}'";
    } elseif (is_string($where)) {
        $whereStr .= $where;
    }
    return "{$type} {$field} from {$table} where $whereStr";
}

/**
 * 数组交集
 * @param array arg
 * @param array arg1
 * @param array arg2
 * @param array arg...
 * @param int return_value (返回第几个数组的值)
 * @return array
 */
function arrayIntersect()
{
    $arr = func_get_args();
    $return_value = end($arr);
    unset($arr[count($arr) - 1]);
    $return_arr = [];
    foreach ((array)$arr as $k => $v) {
        foreach ($v as $ks => $vs) {
            if (count(array_column($arr, $ks)) == count($arr)) $return_arr[$ks] = $arr[$return_value][$ks];
        }
    }
    return $return_arr;
}

/**
 * 自动加载模块
 */
function loadModel()
{
    //加载composer
    $getProject = getFolder(__DIR__, 'kkw');
    include_once($getProject . "\\vendor\\autoload.php");
    spl_autoload_register(function ($class) use ($getProject) {
        if (file_exists($getProject . "{$class}.php")) {
            include $getProject . "{$class}.php";
        }
    });
}

/**
 * 获取指定目录文件下的路径
 * @param string $folder
 * @param string $default
 * @return string
 */
function getFolder($folder = '', $default = '')
{
    if ($folder) {
        if (basename($folder) == $default) {
            return $folder;
        } else {
            return getFolder(dirname($folder), $default);
        }
    }
}

/**
 * 参数处理
 * @param string $key
 * @param string $value
 * @param string $type (array|string)
 * @return array|mixed|null[]
 */
function requestData($key = '', $value = '', $type = 'array')
{
    $data = request()->all();
    if (isset($data['message'])) $data = $data['message'];
    if ($key) {
        if (isset($data[$key])) {
            $data = [$key => $data[$key]];
        } else {
            $data = [$key => $value];
        }
    }
    foreach ($data as $k => $v) $data[$k] = trim($v);
    $function = 'to' . ucfirst($type);
    return $function($data);
}

/**
 * 字符串化
 * @param array $data
 * @return string
 */
function toString($data = [])
{
    return strval(reset($data));
}

/**
 * 整型化
 * @param array $data
 * @return int
 */
function toInt($data = [])
{
    return intval(reset($data));
}

/**
 * 去除左右两边符号
 * @param string $string
 * @param string|array $charList
 * @return string
 */
function trimList($string = '', $charList = '')
{
    if (is_array($charList)) {
        foreach ($charList as $v) {
            $string = trim($string, $v);
        }
    } elseif (is_string($charList)) {
        $string = trim($string, $charList);
    }
    return $string;
}

/**
 * 转换数组
 * @param object|string $data
 * @return mixed
 */
function toArray($data)
{
    if (is_string($data)) {
        return json_decode($data, true);
    } else {
        return json_decode(json_encode($data), true);
    }
}

/**
 * json字符串转数组
 * @param string $str
 * @return mixed
 */
function jsonToArray($str = '')
{
    return json_decode($str, true);
}

/**
 * 转换成json字符串
 * @param array|object|string|callable|int $data
 * @return false|string
 */
function toJson($data)
{
    return json_encode($data);
}

/**
 * 获取配置文件
 * @param $config
 * @param string $key
 * @return mixed
 */
function getConfig($config, $key = '')
{
    $config = include(getFolder(__DIR__, 'kkw') . "/config/{$config}.php");
    if ($key) $config = $config[$key];
    return $config;
}

function startBusinessWorker()
{

    $BusinessWorker = getConfig('workman', 'BusinessWorker');
    $worker = new BusinessWorker();
    $worker->name = $BusinessWorker['name'];
    $worker->count = $BusinessWorker['count'];
    $worker->registerAddress = "{$BusinessWorker['ip']}:{$BusinessWorker['port']}";
    $worker->eventHandler = \App\Workerman\Events::class;
}

function startGateWay()
{
    $BusinessWorker = getConfig('workman', 'BusinessWorker');
    $Gateway = getConfig('workman', 'Gateway');
    // gateway 进程，这里使用Text协议，可以用telnet测试
    $gateway = new Gateway("websocket://{$Gateway['ip']}:{$Gateway['port']}");
    // gateway名称，status方便查看
    $gateway->name = $Gateway['name'];
    // gateway进程数
    $gateway->count = $Gateway['count'];
    // 本机ip，分布式部署时使用内网ip
    $gateway->lanIp = $Gateway['lanIp'];
    // 内部通讯起始端口，假如$gateway->count=4，起始端口为4000
    // 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
    $gateway->startPort = $Gateway['startPort'];
    // 服务注册地址
    $gateway->registerAddress = "{$BusinessWorker['ip']}:{$BusinessWorker['port']}";
    $gateway->disableInput = $Gateway['disableInput'];
    // 心跳间隔
    $gateway->pingInterval = $Gateway['pingInterval'];
    // 心跳数据
    $gateway->pingData = $Gateway['pingData'];
}

function startRegister()
{
    $Register = getConfig('workman', 'Register');
    // register 必须是text协议
    new Register("text://{$Register['ip']}:{$Register['port']}");
}
